home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-10-28 | 64.2 KB | 1,981 lines |
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- NNNNAAAAMMMMEEEE
- perlxs - XS language reference manual
-
- DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
- IIIInnnnttttrrrroooodddduuuuccccttttiiiioooonnnn
-
- XS is a language used to create an extension interface
- between Perl and some C library which one wishes to use with
- Perl. The XS interface is combined with the library to
- create a new library which can be linked to Perl. An XXXXSSSSUUUUBBBB
- is a function in the XS language and is the core component
- of the Perl application interface.
-
- The XS compiler is called xxxxssssuuuubbbbpppppppp. This compiler will embed
- the constructs necessary to let an XSUB, which is really a C
- function in disguise, manipulate Perl values and creates the
- glue necessary to let Perl access the XSUB. The compiler
- uses ttttyyyyppppeeeemmmmaaaappppssss to determine how to map C function parameters
- and variables to Perl values. The default typemap handles
- many common C types. A supplement typemap must be created
- to handle special structures and types for the library being
- linked.
-
- See the _p_e_r_l_x_s_t_u_t manpage for a tutorial on the whole
- extension creation process.
-
- Note: For many extensions, Dave Beazley's SWIG system
- provides a significantly more convenient mechanism for
- creating the XS glue code. See the section on
- /_w_w_w._c_s._u_t_a_h._e_d_u/~_b_e_a_z_l_e_y/_S_W_I_G in the _h_t_t_p: manpage for more
- information.
-
- OOOOnnnn TTTThhhheeee RRRRooooaaaadddd
-
- Many of the examples which follow will concentrate on
- creating an interface between Perl and the ONC+ RPC bind
- library functions. The _r_p_c_b__g_e_t_t_i_m_e() function is used to
- demonstrate many features of the XS language. This function
- has two parameters; the first is an input parameter and the
- second is an output parameter. The function also returns a
- status value.
-
- bool_t rpcb_gettime(const char *host, time_t *timep);
-
- From C this function will be called with the following
- statements.
-
- #include <rpc/rpc.h>
- bool_t status;
- time_t timep;
- status = rpcb_gettime( "localhost", &timep );
-
-
-
-
- Page 1 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- If an XSUB is created to offer a direct translation between
- this function and Perl, then this XSUB will be used from
- Perl with the following code. The $status and $timep
- variables will contain the output of the function.
-
- use RPC;
- $status = rpcb_gettime( "localhost", $timep );
-
- The following XS file shows an XS subroutine, or XSUB, which
- demonstrates one possible interface to the _r_p_c_b__g_e_t_t_i_m_e()
- function. This XSUB represents a direct translation between
- C and Perl and so preserves the interface even from Perl.
- This XSUB will be invoked from Perl with the usage shown
- above. Note that the first three #include statements, for
- EXTERN.h, perl.h, and XSUB.h, will always be present at the
- beginning of an XS file. This approach and others will be
- expanded later in this document.
-
- #include "EXTERN.h"
- #include "perl.h"
- #include "XSUB.h"
- #include <rpc/rpc.h>
-
- MODULE = RPC PACKAGE = RPC
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep
- OUTPUT:
- timep
-
- Any extension to Perl, including those containing XSUBs,
- should have a Perl module to serve as the bootstrap which
- pulls the extension into Perl. This module will export the
- extension's functions and variables to the Perl program and
- will cause the extension's XSUBs to be linked into Perl.
- The following module will be used for most of the examples
- in this document and should be used from Perl with the use
- command as shown earlier. Perl modules are explained in
- more detail later in this document.
-
- package RPC;
-
- require Exporter;
- require DynaLoader;
- @ISA = qw(Exporter DynaLoader);
- @EXPORT = qw( rpcb_gettime );
-
- bootstrap RPC;
- 1;
-
-
-
-
- Page 2 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- Throughout this document a variety of interfaces to the
- _r_p_c_b__g_e_t_t_i_m_e() XSUB will be explored. The XSUBs will take
- their parameters in different orders or will take different
- numbers of parameters. In each case the XSUB is an
- abstraction between Perl and the real C _r_p_c_b__g_e_t_t_i_m_e()
- function, and the XSUB must always ensure that the real
- _r_p_c_b__g_e_t_t_i_m_e() function is called with the correct
- parameters. This abstraction will allow the programmer to
- create a more Perl-like interface to the C function.
-
- TTTThhhheeee AAAAnnnnaaaattttoooommmmyyyy ooooffff aaaannnn XXXXSSSSUUUUBBBB
-
- The following XSUB allows a Perl program to access a C
- library function called _s_i_n(). The XSUB will imitate the C
- function which takes a single argument and returns a single
- value.
-
- double
- sin(x)
- double x
-
- When using C pointers the indirection operator * should be
- considered part of the type and the address operator &
- should be considered part of the variable, as is
- demonstrated in the _r_p_c_b__g_e_t_t_i_m_e() function above. See the
- section on typemaps for more about handling qualifiers and
- unary operators in C types.
-
- The function name and the return type must be placed on
- separate lines.
-
- INCORRECT CORRECT
-
- double sin(x) double
- double x sin(x)
- double x
-
- The function body may be indented or left-adjusted. The
- following example shows a function with its body left-
- adjusted. Most examples in this document will indent the
- body.
-
- CORRECT
-
- double
- sin(x)
- double x
-
-
-
-
-
-
-
-
- Page 3 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- TTTThhhheeee AAAArrrrgggguuuummmmeeeennnntttt SSSSttttaaaacccckkkk
-
- The argument stack is used to store the values which are
- sent as parameters to the XSUB and to store the XSUB's
- return value. In reality all Perl functions keep their
- values on this stack at the same time, each limited to its
- own range of positions on the stack. In this document the
- first position on that stack which belongs to the active
- function will be referred to as position 0 for that
- function.
-
- XSUBs refer to their stack arguments with the macro SSSSTTTT((((xxxx)))),
- where _x refers to a position in this XSUB's part of the
- stack. Position 0 for that function would be known to the
- XSUB as _S_T(0). The XSUB's incoming parameters and outgoing
- return values always begin at _S_T(0). For many simple cases
- the xxxxssssuuuubbbbpppppppp compiler will generate the code necessary to
- handle the argument stack by embedding code fragments found
- in the typemaps. In more complex cases the programmer must
- supply the code.
-
- TTTThhhheeee RRRREEEETTTTVVVVAAAALLLL VVVVaaaarrrriiiiaaaabbbblllleeee
-
- The RETVAL variable is a magic variable which always matches
- the return type of the C library function. The xxxxssssuuuubbbbpppppppp
- compiler will supply this variable in each XSUB and by
- default will use it to hold the return value of the C
- library function being called. In simple cases the value of
- RETVAL will be placed in _S_T(0) of the argument stack where
- it can be received by Perl as the return value of the XSUB.
-
- If the XSUB has a return type of void then the compiler will
- not supply a RETVAL variable for that function. When using
- the PPCODE: directive the RETVAL variable is not needed,
- unless used explicitly.
-
- If PPCODE: directive is not used, void return value should
- be used only for subroutines which do not return a value,
- _e_v_e_n _i_f CODE: directive is used which sets _S_T(0)
- explicitly.
-
- Older versions of this document recommended to use void
- return value in such cases. It was discovered that this
- could lead to segfaults in cases when XSUB was _t_r_u_e_l_y void.
- This practice is now deprecated, and may be not supported at
- some future version. Use the return value SV * in such
- cases. (Currently xsubpp contains some heuristic code which
- tries to disambiguate between "truely-void" and "old-
- practice-declared-as-void" functions. Hence your code is at
- mercy of this heuristics unless you use SV * as return
- value.)
-
-
-
-
- Page 4 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- TTTThhhheeee MMMMOOOODDDDUUUULLLLEEEE KKKKeeeeyyyywwwwoooorrrrdddd
-
- The MODULE keyword is used to start the XS code and to
- specify the package of the functions which are being
- defined. All text preceding the first MODULE keyword is
- considered C code and is passed through to the output
- untouched. Every XS module will have a bootstrap function
- which is used to hook the XSUBs into Perl. The package name
- of this bootstrap function will match the value of the last
- MODULE statement in the XS source files. The value of
- MODULE should always remain constant within the same XS
- file, though this is not required.
-
- The following example will start the XS code and will place
- all functions in a package named RPC.
-
- MODULE = RPC
-
-
- TTTThhhheeee PPPPAAAACCCCKKKKAAAAGGGGEEEE KKKKeeeeyyyywwwwoooorrrrdddd
-
- When functions within an XS source file must be separated
- into packages the PACKAGE keyword should be used. This
- keyword is used with the MODULE keyword and must follow
- immediately after it when used.
-
- MODULE = RPC PACKAGE = RPC
-
- [ XS code in package RPC ]
-
- MODULE = RPC PACKAGE = RPCB
-
- [ XS code in package RPCB ]
-
- MODULE = RPC PACKAGE = RPC
-
- [ XS code in package RPC ]
-
- Although this keyword is optional and in some cases provides
- redundant information it should always be used. This
- keyword will ensure that the XSUBs appear in the desired
- package.
-
- TTTThhhheeee PPPPRRRREEEEFFFFIIIIXXXX KKKKeeeeyyyywwwwoooorrrrdddd
-
- The PREFIX keyword designates prefixes which should be
- removed from the Perl function names. If the C function is
- rpcb_gettime() and the PREFIX value is rpcb_ then Perl will
- see this function as gettime().
-
- This keyword should follow the PACKAGE keyword when used.
- If PACKAGE is not used then PREFIX should follow the MODULE
-
-
-
- Page 5 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- keyword.
-
- MODULE = RPC PREFIX = rpc_
-
- MODULE = RPC PACKAGE = RPCB PREFIX = rpcb_
-
-
- TTTThhhheeee OOOOUUUUTTTTPPPPUUUUTTTT:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The OUTPUT: keyword indicates that certain function
- parameters should be updated (new values made visible to
- Perl) when the XSUB terminates or that certain values should
- be returned to the calling Perl function. For simple
- functions, such as the _s_i_n() function above, the RETVAL
- variable is automatically designated as an output value. In
- more complex functions the xxxxssssuuuubbbbpppppppp compiler will need help to
- determine which variables are output variables.
-
- This keyword will normally be used to complement the CODE:
- keyword. The RETVAL variable is not recognized as an output
- variable when the CODE: keyword is present. The OUTPUT:
- keyword is used in this situation to tell the compiler that
- RETVAL really is an output variable.
-
- The OUTPUT: keyword can also be used to indicate that
- function parameters are output variables. This may be
- necessary when a parameter has been modified within the
- function and the programmer would like the update to be seen
- by Perl.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep
- OUTPUT:
- timep
-
- The OUTPUT: keyword will also allow an output parameter to
- be mapped to a matching piece of code rather than to a
- typemap.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep
- OUTPUT:
- timep sv_setnv(ST(1), (double)timep);
-
- xxxxssssuuuubbbbpppppppp emits an automatic SvSETMAGIC() for all parameters in
- the OUTPUT section of the XSUB, except RETVAL. This is the
- usually desired behavior, as it takes care of properly
- invoking 'set' magic on output parameters (needed for hash
-
-
-
- Page 6 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- or array element parameters that must be created if they
- didn't exist). If for some reason, this behavior is not
- desired, the OUTPUT section may contain a SETMAGIC: DISABLE
- line to disable it for the remainder of the parameters in
- the OUTPUT section. Likewise, SETMAGIC: ENABLE can be used
- to reenable it for the remainder of the OUTPUT section. See
- the _p_e_r_l_g_u_t_s manpage for more details about 'set' magic.
-
- TTTThhhheeee CCCCOOOODDDDEEEE:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- This keyword is used in more complicated XSUBs which require
- special handling for the C function. The RETVAL variable is
- available but will not be returned unless it is specified
- under the OUTPUT: keyword.
-
- The following XSUB is for a C function which requires
- special handling of its parameters. The Perl usage is given
- first.
-
- $status = rpcb_gettime( "localhost", $timep );
-
- The XSUB follows.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t timep
- CODE:
- RETVAL = rpcb_gettime( host, &timep );
- OUTPUT:
- timep
- RETVAL
-
-
- TTTThhhheeee IIIINNNNIIIITTTT:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The INIT: keyword allows initialization to be inserted into
- the XSUB before the compiler generates the call to the C
- function. Unlike the CODE: keyword above, this keyword does
- not affect the way the compiler handles RETVAL.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep
- INIT:
- printf("# Host is %s\n", host );
- OUTPUT:
- timep
-
-
-
-
-
-
- Page 7 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- TTTThhhheeee NNNNOOOO____IIIINNNNIIIITTTT KKKKeeeeyyyywwwwoooorrrrdddd
-
- The NO_INIT keyword is used to indicate that a function
- parameter is being used only as an output value. The xxxxssssuuuubbbbpppppppp
- compiler will normally generate code to read the values of
- all function parameters from the argument stack and assign
- them to C variables upon entry to the function. NO_INIT
- will tell the compiler that some parameters will be used for
- output rather than for input and that they will be handled
- before the function terminates.
-
- The following example shows a variation of the
- _r_p_c_b__g_e_t_t_i_m_e() function. This function uses the timep
- variable only as an output variable and does not care about
- its initial contents.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep = NO_INIT
- OUTPUT:
- timep
-
-
- IIIInnnniiiittttiiiiaaaalllliiiizzzziiiinnnngggg FFFFuuuunnnnccccttttiiiioooonnnn PPPPaaaarrrraaaammmmeeeetttteeeerrrrssss
-
- Function parameters are normally initialized with their
- values from the argument stack. The typemaps contain the
- code segments which are used to transfer the Perl values to
- the C parameters. The programmer, however, is allowed to
- override the typemaps and supply alternate (or additional)
- initialization code.
-
- The following code demonstrates how to supply initialization
- code for function parameters. The initialization code is
- eval'd within double quotes by the compiler before it is
- added to the output so anything which should be interpreted
- literally [mainly $, @, or \\] must be protected with
- backslashes. The variables $var, $arg, and $type can be
- used as in typemaps.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host = (char *)SvPV($arg,PL_na);
- time_t &timep = 0;
- OUTPUT:
- timep
-
- This should not be used to supply default values for
- parameters. One would normally use this when a function
- parameter must be processed by another library function
- before it can be used. Default parameters are covered in
-
-
-
- Page 8 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- the next section.
-
- If the initialization begins with =, then it is output on
- the same line where the input variable is declared. If the
- initialization begins with ; or +, then it is output after
- all of the input variables have been declared. The = and ;
- cases replace the initialization normally supplied from the
- typemap. For the + case, the initialization from the
- typemap will preceed the initialization code included after
- the +. A global variable, %v, is available for the truely
- rare case where information from one initialization is
- needed in another initialization.
-
- bool_t
- rpcb_gettime(host,timep)
- time_t &timep ; /*\$v{time}=@{[$v{time}=$arg]}*/
- char *host + SvOK($v{time}) ? SvPV($arg,PL_na) : NULL;
- OUTPUT:
- timep
-
-
- DDDDeeeeffffaaaauuuulllltttt PPPPaaaarrrraaaammmmeeeetttteeeerrrr VVVVaaaalllluuuueeeessss
-
- Default values can be specified for function parameters by
- placing an assignment statement in the parameter list. The
- default value may be a number or a string. Defaults should
- always be used on the right-most parameters only.
-
- To allow the XSUB for _r_p_c_b__g_e_t_t_i_m_e() to have a default host
- value the parameters to the XSUB could be rearranged. The
- XSUB will then call the real _r_p_c_b__g_e_t_t_i_m_e() function with
- the parameters in the correct order. Perl will call this
- XSUB with either of the following statements.
-
- $status = rpcb_gettime( $timep, $host );
-
- $status = rpcb_gettime( $timep );
-
- The XSUB will look like the code which follows. A CODE:
- block is used to call the real _r_p_c_b__g_e_t_t_i_m_e() function with
- the parameters in the correct order for that function.
-
- bool_t
- rpcb_gettime(timep,host="localhost")
- char *host
- time_t timep = NO_INIT
- CODE:
- RETVAL = rpcb_gettime( host, &timep );
- OUTPUT:
- timep
- RETVAL
-
-
-
-
- Page 9 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- TTTThhhheeee PPPPRRRREEEEIIIINNNNIIIITTTT:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The PREINIT: keyword allows extra variables to be declared
- before the typemaps are expanded. If a variable is declared
- in a CODE: block then that variable will follow any typemap
- code. This may result in a C syntax error. To force the
- variable to be declared before the typemap code, place it
- into a PREINIT: block. The PREINIT: keyword may be used one
- or more times within an XSUB.
-
- The following examples are equivalent, but if the code is
- using complex typemaps then the first example is safer.
-
- bool_t
- rpcb_gettime(timep)
- time_t timep = NO_INIT
- PREINIT:
- char *host = "localhost";
- CODE:
- RETVAL = rpcb_gettime( host, &timep );
- OUTPUT:
- timep
- RETVAL
-
- A correct, but error-prone example.
-
- bool_t
- rpcb_gettime(timep)
- time_t timep = NO_INIT
- CODE:
- char *host = "localhost";
- RETVAL = rpcb_gettime( host, &timep );
- OUTPUT:
- timep
- RETVAL
-
-
- TTTThhhheeee SSSSCCCCOOOOPPPPEEEE:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The SCOPE: keyword allows scoping to be enabled for a
- particular XSUB. If enabled, the XSUB will invoke ENTER and
- LEAVE automatically.
-
- To support potentially complex type mappings, if a typemap
- entry used by this XSUB contains a comment like /*scope*/
- then scoping will automatically be enabled for that XSUB.
-
- To enable scoping:
-
- SCOPE: ENABLE
-
- To disable scoping:
-
-
-
- Page 10 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- SCOPE: DISABLE
-
-
- TTTThhhheeee IIIINNNNPPPPUUUUTTTT:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The XSUB's parameters are usually evaluated immediately
- after entering the XSUB. The INPUT: keyword can be used to
- force those parameters to be evaluated a little later. The
- INPUT: keyword can be used multiple times within an XSUB and
- can be used to list one or more input variables. This
- keyword is used with the PREINIT: keyword.
-
- The following example shows how the input parameter timep
- can be evaluated late, after a PREINIT.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- PREINIT:
- time_t tt;
- INPUT:
- time_t timep
- CODE:
- RETVAL = rpcb_gettime( host, &tt );
- timep = tt;
- OUTPUT:
- timep
- RETVAL
-
- The next example shows each input parameter evaluated late.
-
- bool_t
- rpcb_gettime(host,timep)
- PREINIT:
- time_t tt;
- INPUT:
- char *host
- PREINIT:
- char *h;
- INPUT:
- time_t timep
- CODE:
- h = host;
- RETVAL = rpcb_gettime( h, &tt );
- timep = tt;
- OUTPUT:
- timep
- RETVAL
-
-
-
-
-
-
-
- Page 11 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- VVVVaaaarrrriiiiaaaabbbblllleeee----lllleeeennnnggggtttthhhh PPPPaaaarrrraaaammmmeeeetttteeeerrrr LLLLiiiissssttttssss
-
- XSUBs can have variable-length parameter lists by specifying
- an ellipsis (...) in the parameter list. This use of the
- ellipsis is similar to that found in ANSI C. The programmer
- is able to determine the number of arguments passed to the
- XSUB by examining the items variable which the xxxxssssuuuubbbbpppppppp
- compiler supplies for all XSUBs. By using this mechanism
- one can create an XSUB which accepts a list of parameters of
- unknown length.
-
- The _h_o_s_t parameter for the _r_p_c_b__g_e_t_t_i_m_e() XSUB can be
- optional so the ellipsis can be used to indicate that the
- XSUB will take a variable number of parameters. Perl should
- be able to call this XSUB with either of the following
- statements.
-
- $status = rpcb_gettime( $timep, $host );
-
- $status = rpcb_gettime( $timep );
-
- The XS code, with ellipsis, follows.
-
- bool_t
- rpcb_gettime(timep, ...)
- time_t timep = NO_INIT
- PREINIT:
- char *host = "localhost";
- CODE:
- if( items > 1 )
- host = (char *)SvPV(ST(1), PL_na);
- RETVAL = rpcb_gettime( host, &timep );
- OUTPUT:
- timep
- RETVAL
-
-
- TTTThhhheeee CCCC____AAAARRRRGGGGSSSS:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The C_ARGS: keyword allows creating of XSUBS which have
- different calling sequence from Perl than from C, without a
- need to write CODE: or CPPCODE: section. The contents of
- the C_ARGS: paragraph is put as the argument to the called C
- function without any change.
-
- For example, suppose that C function is declared as
-
- symbolic nth_derivative(int n, symbolic function, int flags);
-
- and that the default flags are kept in a global C variable
- default_flags. Suppose that you want to create an interface
- which is called as
-
-
-
- Page 12 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- $second_deriv = $function->nth_derivative(2);
-
- To do this, declare the XSUB as
-
- symbolic
- nth_derivative(function, n)
- symbolic function
- int n
- C_ARGS:
- n, function, default_flags
-
-
- TTTThhhheeee PPPPPPPPCCCCOOOODDDDEEEE:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The PPCODE: keyword is an alternate form of the CODE:
- keyword and is used to tell the xxxxssssuuuubbbbpppppppp compiler that the
- programmer is supplying the code to control the argument
- stack for the XSUBs return values. Occasionally one will
- want an XSUB to return a list of values rather than a single
- value. In these cases one must use PPCODE: and then
- explicitly push the list of values on the stack. The
- PPCODE: and CODE: keywords are not used together within the
- same XSUB.
-
- The following XSUB will call the C _r_p_c_b__g_e_t_t_i_m_e() function
- and will return its two output values, timep and status, to
- Perl as a single list.
-
- void
- rpcb_gettime(host)
- char *host
- PREINIT:
- time_t timep;
- bool_t status;
- PPCODE:
- status = rpcb_gettime( host, &timep );
- EXTEND(SP, 2);
- PUSHs(sv_2mortal(newSViv(status)));
- PUSHs(sv_2mortal(newSViv(timep)));
-
- Notice that the programmer must supply the C code necessary
- to have the real _r_p_c_b__g_e_t_t_i_m_e() function called and to have
- the return values properly placed on the argument stack.
-
- The void return type for this function tells the xxxxssssuuuubbbbpppppppp
- compiler that the RETVAL variable is not needed or used and
- that it should not be created. In most scenarios the void
- return type should be used with the PPCODE: directive.
-
- The _E_X_T_E_N_D() macro is used to make room on the argument
- stack for 2 return values. The PPCODE: directive causes the
- xxxxssssuuuubbbbpppppppp compiler to create a stack pointer available as SP,
-
-
-
- Page 13 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- and it is this pointer which is being used in the _E_X_T_E_N_D()
- macro. The values are then pushed onto the stack with the
- _P_U_S_H_s() macro.
-
- Now the _r_p_c_b__g_e_t_t_i_m_e() function can be used from Perl with
- the following statement.
-
- ($status, $timep) = rpcb_gettime("localhost");
-
- When handling output parameters with a PPCODE section, be
- sure to handle 'set' magic properly. See the _p_e_r_l_g_u_t_s
- manpage for details about 'set' magic.
-
- RRRReeeettttuuuurrrrnnnniiiinnnngggg UUUUnnnnddddeeeeffff AAAAnnnndddd EEEEmmmmppppttttyyyy LLLLiiiissssttttssss
-
- Occasionally the programmer will want to return simply undef
- or an empty list if a function fails rather than a separate
- status value. The _r_p_c_b__g_e_t_t_i_m_e() function offers just this
- situation. If the function succeeds we would like to have
- it return the time and if it fails we would like to have
- undef returned. In the following Perl code the value of
- $timep will either be undef or it will be a valid time.
-
- $timep = rpcb_gettime( "localhost" );
-
- The following XSUB uses the SV * return type as a mnemonic
- only, and uses a CODE: block to indicate to the compiler
- that the programmer has supplied all the necessary code.
- The _s_v__n_e_w_m_o_r_t_a_l() call will initialize the return value to
- undef, making that the default return value.
-
- SV *
- rpcb_gettime(host)
- char * host
- PREINIT:
- time_t timep;
- bool_t x;
- CODE:
- ST(0) = sv_newmortal();
- if( rpcb_gettime( host, &timep ) )
- sv_setnv( ST(0), (double)timep);
-
- The next example demonstrates how one would place an
- explicit undef in the return value, should the need arise.
-
-
-
-
-
-
-
-
-
-
-
- Page 14 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- SV *
- rpcb_gettime(host)
- char * host
- PREINIT:
- time_t timep;
- bool_t x;
- CODE:
- ST(0) = sv_newmortal();
- if( rpcb_gettime( host, &timep ) ){
- sv_setnv( ST(0), (double)timep);
- }
- else{
- ST(0) = &PL_sv_undef;
- }
-
- To return an empty list one must use a PPCODE: block and
- then not push return values on the stack.
-
- void
- rpcb_gettime(host)
- char *host
- PREINIT:
- time_t timep;
- PPCODE:
- if( rpcb_gettime( host, &timep ) )
- PUSHs(sv_2mortal(newSViv(timep)));
- else{
- /* Nothing pushed on stack, so an empty */
- /* list is implicitly returned. */
- }
-
- Some people may be inclined to include an explicit return in
- the above XSUB, rather than letting control fall through to
- the end. In those situations XSRETURN_EMPTY should be used,
- instead. This will ensure that the XSUB stack is properly
- adjusted. Consult the section on _A_P_I _L_I_S_T_I_N_G in the
- _p_e_r_l_g_u_t_s manpage for other XSRETURN macros.
-
- TTTThhhheeee RRRREEEEQQQQUUUUIIIIRRRREEEE:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The REQUIRE: keyword is used to indicate the minimum version
- of the xxxxssssuuuubbbbpppppppp compiler needed to compile the XS module. An
- XS module which contains the following statement will
- compile with only xxxxssssuuuubbbbpppppppp version 1.922 or greater:
-
- REQUIRE: 1.922
-
-
- TTTThhhheeee CCCCLLLLEEEEAAAANNNNUUUUPPPP:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- This keyword can be used when an XSUB requires special
- cleanup procedures before it terminates. When the CLEANUP:
-
-
-
- Page 15 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- keyword is used it must follow any CODE:, PPCODE:, or
- OUTPUT: blocks which are present in the XSUB. The code
- specified for the cleanup block will be added as the last
- statements in the XSUB.
-
- TTTThhhheeee BBBBOOOOOOOOTTTT:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The BOOT: keyword is used to add code to the extension's
- bootstrap function. The bootstrap function is generated by
- the xxxxssssuuuubbbbpppppppp compiler and normally holds the statements
- necessary to register any XSUBs with Perl. With the BOOT:
- keyword the programmer can tell the compiler to add extra
- statements to the bootstrap function.
-
- This keyword may be used any time after the first MODULE
- keyword and should appear on a line by itself. The first
- blank line after the keyword will terminate the code block.
-
- BOOT:
- # The following message will be printed when the
- # bootstrap function executes.
- printf("Hello from the bootstrap!\n");
-
-
- TTTThhhheeee VVVVEEEERRRRSSSSIIIIOOOONNNNCCCCHHHHEEEECCCCKKKK:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The VERSIONCHECK: keyword corresponds to xxxxssssuuuubbbbpppppppp's
- -versioncheck and -noversioncheck options. This keyword
- overrides the command line options. Version checking is
- enabled by default. When version checking is enabled the XS
- module will attempt to verify that its version matches the
- version of the PM module.
-
- To enable version checking:
-
- VERSIONCHECK: ENABLE
-
- To disable version checking:
-
- VERSIONCHECK: DISABLE
-
-
- TTTThhhheeee PPPPRRRROOOOTTTTOOOOTTTTYYYYPPPPEEEESSSS:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The PROTOTYPES: keyword corresponds to xxxxssssuuuubbbbpppppppp's -prototypes
- and -noprototypes options. This keyword overrides the
- command line options. Prototypes are enabled by default.
- When prototypes are enabled XSUBs will be given Perl
- prototypes. This keyword may be used multiple times in an
- XS module to enable and disable prototypes for different
- parts of the module.
-
-
-
-
- Page 16 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- To enable prototypes:
-
- PROTOTYPES: ENABLE
-
- To disable prototypes:
-
- PROTOTYPES: DISABLE
-
-
- TTTThhhheeee PPPPRRRROOOOTTTTOOOOTTTTYYYYPPPPEEEE:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- This keyword is similar to the PROTOTYPES: keyword above but
- can be used to force xxxxssssuuuubbbbpppppppp to use a specific prototype for
- the XSUB. This keyword overrides all other prototype
- options and keywords but affects only the current XSUB.
- Consult the Prototypes entry in the _p_e_r_l_s_u_b manpage for
- information about Perl prototypes.
-
- bool_t
- rpcb_gettime(timep, ...)
- time_t timep = NO_INIT
- PROTOTYPE: $;$
- PREINIT:
- char *host = "localhost";
- CODE:
- if( items > 1 )
- host = (char *)SvPV(ST(1), PL_na);
- RETVAL = rpcb_gettime( host, &timep );
- OUTPUT:
- timep
- RETVAL
-
-
- TTTThhhheeee AAAALLLLIIIIAAAASSSS:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The ALIAS: keyword allows an XSUB to have two or more unique
- Perl names and to know which of those names was used when it
- was invoked. The Perl names may be fully-qualified with
- package names. Each alias is given an index. The compiler
- will setup a variable called ix which contain the index of
- the alias which was used. When the XSUB is called with its
- declared name ix will be 0.
-
- The following example will create aliases FOO::gettime() and
- BAR::getit() for this function.
-
-
-
-
-
-
-
-
-
-
- Page 17 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep
- ALIAS:
- FOO::gettime = 1
- BAR::getit = 2
- INIT:
- printf("# ix = %d\n", ix );
- OUTPUT:
- timep
-
-
- TTTThhhheeee IIIINNNNTTTTEEEERRRRFFFFAAAACCCCEEEE:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- This keyword declares the current XSUB as a keeper of the
- given calling signature. If some text follows this keyword,
- it is considered as a list of functions which have this
- signature, and should be attached to XSUBs.
-
- Say, if you have 4 functions _m_u_l_t_i_p_l_y(), _d_i_v_i_d_e(), _a_d_d(),
- _s_u_b_t_r_a_c_t() all having the signature
-
- symbolic f(symbolic, symbolic);
-
- you code them all by using XSUB
-
- symbolic
- interface_s_ss(arg1, arg2)
- symbolic arg1
- symbolic arg2
- INTERFACE:
- multiply divide
- add subtract
-
- The advantage of this approach comparing to ALIAS: keyword
- is that one can attach an extra function _r_e_m_a_i_n_d_e_r() at
- runtime by using
-
- CV *mycv = _n_e_w_X_S_p_r_o_t_o("Symbolic::remainder",
- XS_Symbolic_interface_s_ss, __FILE__,
- "$$");
- _X_S_I_N_T_E_R_F_A_C_E__F_U_N_C__S_E_T(mycv, remainder);
-
- (This example supposes that there was no INTERFACE_MACRO:
- section, otherwise one needs to use something else instead
- of XSINTERFACE_FUNC_SET.)
-
- TTTThhhheeee IIIINNNNTTTTEEEERRRRFFFFAAAACCCCEEEE____MMMMAAAACCCCRRRROOOO:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- This keyword allows one to define an INTERFACE using a
- different way to extract a function pointer from an XSUB.
-
-
-
- Page 18 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- The text which follows this keyword should give the name of
- macros which would extract/set a function pointer. The
- extractor macro is given return type, CV*, and
- XSANY.any_dptr for this CV*. The setter macro is given cv,
- and the function pointer.
-
- The default value is XSINTERFACE_FUNC and
- XSINTERFACE_FUNC_SET. An INTERFACE keyword with an empty
- list of functions can be omitted if INTERFACE_MACRO keyword
- is used.
-
- Suppose that in the previous example functions pointers for
- _m_u_l_t_i_p_l_y(), _d_i_v_i_d_e(), _a_d_d(), _s_u_b_t_r_a_c_t() are kept in a global
- C array fp[] with offsets being multiply_off, divide_off,
- add_off, subtract_off. Then one can use
-
- #define XSINTERFACE_FUNC_BYOFFSET(ret,cv,f) \
- ((XSINTERFACE_CVT(ret,))fp[CvXSUBANY(cv).any_i32])
- #define XSINTERFACE_FUNC_BYOFFSET_set(cv,f) \
- CvXSUBANY(cv).any_i32 = CAT2( f, _off )
-
- in C section,
-
- symbolic
- interface_s_ss(arg1, arg2)
- symbolic arg1
- symbolic arg2
- INTERFACE_MACRO:
- XSINTERFACE_FUNC_BYOFFSET
- XSINTERFACE_FUNC_BYOFFSET_set
- INTERFACE:
- multiply divide
- add subtract
-
- in XSUB section.
-
- TTTThhhheeee IIIINNNNCCCCLLLLUUUUDDDDEEEE:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- This keyword can be used to pull other files into the XS
- module. The other files may have XS code. INCLUDE: can
- also be used to run a command to generate the XS code to be
- pulled into the module.
-
- The file _R_p_c_b_1._x_s_h contains our rpcb_gettime() function:
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep
- OUTPUT:
- timep
-
-
-
-
- Page 19 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- The XS module can use INCLUDE: to pull that file into it.
-
- INCLUDE: Rpcb1.xsh
-
- If the parameters to the INCLUDE: keyword are followed by a
- pipe (|) then the compiler will interpret the parameters as
- a command.
-
- INCLUDE: cat Rpcb1.xsh |
-
-
- TTTThhhheeee CCCCAAAASSSSEEEE:::: KKKKeeeeyyyywwwwoooorrrrdddd
-
- The CASE: keyword allows an XSUB to have multiple distinct
- parts with each part acting as a virtual XSUB. CASE: is
- greedy and if it is used then all other XS keywords must be
- contained within a CASE:. This means nothing may precede
- the first CASE: in the XSUB and anything following the last
- CASE: is included in that case.
-
- A CASE: might switch via a parameter of the XSUB, via the ix
- ALIAS: variable (see the section on _T_h_e _A_L_I_A_S: _K_e_y_w_o_r_d), or
- maybe via the items variable (see the section on _V_a_r_i_a_b_l_e-
- _l_e_n_g_t_h _P_a_r_a_m_e_t_e_r _L_i_s_t_s). The last CASE: becomes the ddddeeeeffffaaaauuuulllltttt
- case if it is not associated with a conditional. The
- following example shows CASE switched via ix with a function
- rpcb_gettime() having an alias x_gettime(). When the
- function is called as rpcb_gettime() its parameters are the
- usual (char *host, time_t *timep), but when the function is
- called as x_gettime() its parameters are reversed, (time_t
- *timep, char *host).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 20 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- long
- rpcb_gettime(a,b)
- CASE: ix == 1
- ALIAS:
- x_gettime = 1
- INPUT:
- # 'a' is timep, 'b' is host
- char *b
- time_t a = NO_INIT
- CODE:
- RETVAL = rpcb_gettime( b, &a );
- OUTPUT:
- a
- RETVAL
- CASE:
- # 'a' is host, 'b' is timep
- char *a
- time_t &b = NO_INIT
- OUTPUT:
- b
- RETVAL
-
- That function can be called with either of the following
- statements. Note the different argument lists.
-
- $status = rpcb_gettime( $host, $timep );
-
- $status = x_gettime( $timep, $host );
-
-
- TTTThhhheeee &&&& UUUUnnnnaaaarrrryyyy OOOOppppeeeerrrraaaattttoooorrrr
-
- The & unary operator is used to tell the compiler that it
- should dereference the object when it calls the C function.
- This is used when a CODE: block is not used and the object
- is a not a pointer type (the object is an int or long but
- not a int* or long*).
-
- The following XSUB will generate incorrect C code. The
- xsubpp compiler will turn this into code which calls
- rpcb_gettime() with parameters (char *host, time_t timep),
- but the real rpcb_gettime() wants the timep parameter to be
- of type time_t* rather than time_t.
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t timep
- OUTPUT:
- timep
-
- That problem is corrected by using the & operator. The
-
-
-
- Page 21 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- xsubpp compiler will now turn this into code which calls
- rpcb_gettime() correctly with parameters (char *host, time_t
- *timep). It does this by carrying the & through, so the
- function call looks like rpcb_gettime(host, &timep).
-
- bool_t
- rpcb_gettime(host,timep)
- char *host
- time_t &timep
- OUTPUT:
- timep
-
-
- IIIInnnnsssseeeerrrrttttiiiinnnngggg CCCCoooommmmmmmmeeeennnnttttssss aaaannnndddd CCCC PPPPrrrreeeepppprrrroooocccceeeessssssssoooorrrr DDDDiiiirrrreeeeccccttttiiiivvvveeeessss
-
- C preprocessor directives are allowed within BOOT:, PREINIT:
- INIT:, CODE:, PPCODE:, and CLEANUP: blocks, as well as
- outside the functions. Comments are allowed anywhere after
- the MODULE keyword. The compiler will pass the preprocessor
- directives through untouched and will remove the commented
- lines.
-
- Comments can be added to XSUBs by placing a # as the first
- non-whitespace of a line. Care should be taken to avoid
- making the comment look like a C preprocessor directive,
- lest it be interpreted as such. The simplest way to prevent
- this is to put whitespace in front of the #.
-
- If you use preprocessor directives to choose one of two
- versions of a function, use
-
- #if ... version1
- #else /* ... version2 */
- #endif
-
- and not
-
- #if ... version1
- #endif
- #if ... version2
- #endif
-
- because otherwise xsubpp will believe that you made a
- duplicate definition of the function. Also, put a blank
- line before the #else/#endif so it will not be seen as part
- of the function body.
-
- UUUUssssiiiinnnngggg XXXXSSSS WWWWiiiitttthhhh CCCC++++++++
-
- If a function is defined as a C++ method then it will assume
- its first argument is an object pointer. The object pointer
- will be stored in a variable called THIS. The object should
-
-
-
- Page 22 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- have been created by C++ with the _n_e_w() function and should
- be blessed by Perl with the _s_v__s_e_t_r_e_f__p_v() macro. The
- blessing of the object by Perl can be handled by a typemap.
- An example typemap is shown at the end of this section.
-
- If the method is defined as static it will call the C++
- function using the _c_l_a_s_s::_m_e_t_h_o_d() syntax. If the method is
- not static the function will be called using the
- THIS->_m_e_t_h_o_d() syntax.
-
- The next examples will use the following C++ class.
-
- class color {
- public:
- color();
- ~color();
- int blue();
- void set_blue( int );
-
- private:
- int c_blue;
- };
-
- The XSUBs for the _b_l_u_e() and _s_e_t__b_l_u_e() methods are defined
- with the class name but the parameter for the object (THIS,
- or "self") is implicit and is not listed.
-
- int
- color::blue()
-
- void
- color::set_blue( val )
- int val
-
- Both functions will expect an object as the first parameter.
- The xsubpp compiler will call that object THIS and will use
- it to call the specified method. So in the C++ code the
- _b_l_u_e() and _s_e_t__b_l_u_e() methods will be called in the
- following manner.
-
- RETVAL = THIS->blue();
-
- THIS->set_blue( val );
-
- If the function's name is DDDDEEEESSSSTTTTRRRROOOOYYYY then the C++ delete
- function will be called and THIS will be given as its
- parameter.
-
- void
- color::DESTROY()
-
- The C++ code will call delete.
-
-
-
- Page 23 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- delete THIS;
-
- If the function's name is nnnneeeewwww then the C++ new function will
- be called to create a dynamic C++ object. The XSUB will
- expect the class name, which will be kept in a variable
- called CLASS, to be given as the first argument.
-
- color *
- color::new()
-
- The C++ code will call new.
-
- RETVAL = new color();
-
- The following is an example of a typemap that could be used
- for this C++ example.
-
- TYPEMAP
- color * O_OBJECT
-
- OUTPUT
- # The Perl object is blessed into 'CLASS', which should be a
- # char* having the name of the package for the blessing.
- O_OBJECT
- sv_setref_pv( $arg, CLASS, (void*)$var );
-
- INPUT
- O_OBJECT
- if( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) )
- $var = ($type)SvIV((SV*)SvRV( $arg ));
- else{
- warn( \"${Package}::$func_name() -- $var is not a blessed SV reference\" );
- XSRETURN_UNDEF;
- }
-
-
- IIIInnnntttteeeerrrrffffaaaacccceeee SSSSttttrrrraaaatttteeeeggggyyyy
-
- When designing an interface between Perl and a C library a
- straight translation from C to XS is often sufficient. The
- interface will often be very C-like and occasionally
- nonintuitive, especially when the C function modifies one of
- its parameters. In cases where the programmer wishes to
- create a more Perl-like interface the following strategy may
- help to identify the more critical parts of the interface.
-
- Identify the C functions which modify their parameters. The
- XSUBs for these functions may be able to return lists to
- Perl, or may be candidates to return undef or an empty list
- in case of failure.
-
- Identify which values are used by only the C and XSUB
-
-
-
- Page 24 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- functions themselves. If Perl does not need to access the
- contents of the value then it may not be necessary to
- provide a translation for that value from C to Perl.
-
- Identify the pointers in the C function parameter lists and
- return values. Some pointers can be handled in XS with the
- & unary operator on the variable name while others will
- require the use of the * operator on the type name. In
- general it is easier to work with the & operator.
-
- Identify the structures used by the C functions. In many
- cases it may be helpful to use the T_PTROBJ typemap for
- these structures so they can be manipulated by Perl as
- blessed objects.
-
- PPPPeeeerrrrllll OOOObbbbjjjjeeeeccccttttssss AAAAnnnndddd CCCC SSSSttttrrrruuuuccccttttuuuurrrreeeessss
-
- When dealing with C structures one should select either
- TTTT____PPPPTTTTRRRROOOOBBBBJJJJ or TTTT____PPPPTTTTRRRRRRRREEEEFFFF for the XS type. Both types are
- designed to handle pointers to complex objects. The
- T_PTRREF type will allow the Perl object to be unblessed
- while the T_PTROBJ type requires that the object be blessed.
- By using T_PTROBJ one can achieve a form of type-checking
- because the XSUB will attempt to verify that the Perl object
- is of the expected type.
-
- The following XS code shows the _g_e_t_n_e_t_c_o_n_f_i_g_e_n_t() function
- which is used with ONC+ TIRPC. The _g_e_t_n_e_t_c_o_n_f_i_g_e_n_t()
- function will return a pointer to a C structure and has the
- C prototype shown below. The example will demonstrate how
- the C pointer will become a Perl reference. Perl will
- consider this reference to be a pointer to a blessed object
- and will attempt to call a destructor for the object. A
- destructor will be provided in the XS source to free the
- memory used by _g_e_t_n_e_t_c_o_n_f_i_g_e_n_t(). Destructors in XS can be
- created by specifying an XSUB function whose name ends with
- the word DDDDEEEESSSSTTTTRRRROOOOYYYY. XS destructors can be used to free memory
- which may have been malloc'd by another XSUB.
-
- struct netconfig *getnetconfigent(const char *netid);
-
- A typedef will be created for struct netconfig. The Perl
- object will be blessed in a class matching the name of the C
- type, with the tag Ptr appended, and the name should not
- have embedded spaces if it will be a Perl package name. The
- destructor will be placed in a class corresponding to the
- class of the object and the PREFIX keyword will be used to
- trim the name to the word DESTROY as Perl will expect.
-
- typedef struct netconfig Netconfig;
-
- MODULE = RPC PACKAGE = RPC
-
-
-
- Page 25 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- Netconfig *
- getnetconfigent(netid)
- char *netid
-
- MODULE = RPC PACKAGE = NetconfigPtr PREFIX = rpcb_
-
- void
- rpcb_DESTROY(netconf)
- Netconfig *netconf
- CODE:
- printf("Now in NetconfigPtr::DESTROY\n");
- free( netconf );
-
- This example requires the following typemap entry. Consult
- the typemap section for more information about adding new
- typemaps for an extension.
-
- TYPEMAP
- Netconfig * T_PTROBJ
-
- This example will be used with the following Perl
- statements.
-
- use RPC;
- $netconf = getnetconfigent("udp");
-
- When Perl destroys the object referenced by $netconf it will
- send the object to the supplied XSUB DESTROY function. Perl
- cannot determine, and does not care, that this object is a C
- struct and not a Perl object. In this sense, there is no
- difference between the object created by the
- _g_e_t_n_e_t_c_o_n_f_i_g_e_n_t() XSUB and an object created by a normal
- Perl subroutine.
-
- TTTThhhheeee TTTTyyyyppppeeeemmmmaaaapppp
-
- The typemap is a collection of code fragments which are used
- by the xxxxssssuuuubbbbpppppppp compiler to map C function parameters and
- values to Perl values. The typemap file may consist of
- three sections labeled TYPEMAP, INPUT, and OUTPUT. The
- INPUT section tells the compiler how to translate Perl
- values into variables of certain C types. The OUTPUT
- section tells the compiler how to translate the values from
- certain C types into values Perl can understand. The
- TYPEMAP section tells the compiler which of the INPUT and
- OUTPUT code fragments should be used to map a given C type
- to a Perl value. Each of the sections of the typemap must
- be preceded by one of the TYPEMAP, INPUT, or OUTPUT
- keywords.
-
- The default typemap in the ext directory of the Perl source
- contains many useful types which can be used by Perl
-
-
-
- Page 26 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- extensions. Some extensions define additional typemaps
- which they keep in their own directory. These additional
- typemaps may reference INPUT and OUTPUT maps in the main
- typemap. The xxxxssssuuuubbbbpppppppp compiler will allow the extension's own
- typemap to override any mappings which are in the default
- typemap.
-
- Most extensions which require a custom typemap will need
- only the TYPEMAP section of the typemap file. The custom
- typemap used in the _g_e_t_n_e_t_c_o_n_f_i_g_e_n_t() example shown earlier
- demonstrates what may be the typical use of extension
- typemaps. That typemap is used to equate a C structure with
- the T_PTROBJ typemap. The typemap used by _g_e_t_n_e_t_c_o_n_f_i_g_e_n_t()
- is shown here. Note that the C type is separated from the
- XS type with a tab and that the C unary operator * is
- considered to be a part of the C type name.
-
- TYPEMAP
- Netconfig *<tab>T_PTROBJ
-
- Here's a more complicated example: suppose that you wanted
- struct netconfig to be blessed into the class Net::Config.
- One way to do this is to use underscores (_) to separate
- package names, as follows:
-
- typedef struct netconfig * Net_Config;
-
- And then provide a typemap entry T_PTROBJ_SPECIAL that maps
- underscores to double-colons (::), and declare Net_Config to
- be of that type:
-
- TYPEMAP
- Net_Config T_PTROBJ_SPECIAL
-
- INPUT
- T_PTROBJ_SPECIAL
- if (sv_derived_from($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\")) {
- IV tmp = SvIV((SV*)SvRV($arg));
- $var = ($type) tmp;
- }
- else
- croak(\"$var is not of type ${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\")
-
- OUTPUT
- T_PTROBJ_SPECIAL
- sv_setref_pv($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\",
- (void*)$var);
-
- The INPUT and OUTPUT sections substitute underscores for
- double-colons on the fly, giving the desired effect. This
- example demonstrates some of the power and versatility of
- the typemap facility.
-
-
-
- Page 27 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS
- File RPC.xs: Interface to some ONC+ RPC bind library
- functions.
-
- #include "EXTERN.h"
- #include "perl.h"
- #include "XSUB.h"
-
- #include <rpc/rpc.h>
-
- typedef struct netconfig Netconfig;
-
- MODULE = RPC PACKAGE = RPC
-
- SV *
- rpcb_gettime(host="localhost")
- char *host
- PREINIT:
- time_t timep;
- CODE:
- ST(0) = sv_newmortal();
- if( rpcb_gettime( host, &timep ) )
- sv_setnv( ST(0), (double)timep );
-
- Netconfig *
- getnetconfigent(netid="udp")
- char *netid
-
- MODULE = RPC PACKAGE = NetconfigPtr PREFIX = rpcb_
-
- void
- rpcb_DESTROY(netconf)
- Netconfig *netconf
- CODE:
- printf("NetconfigPtr::DESTROY\n");
- free( netconf );
-
- File typemap: Custom typemap for RPC.xs.
-
- TYPEMAP
- Netconfig * T_PTROBJ
-
- File RPC.pm: Perl module for the RPC extension.
-
- package RPC;
-
- require Exporter;
- require DynaLoader;
- @ISA = qw(Exporter DynaLoader);
- @EXPORT = qw(rpcb_gettime getnetconfigent);
-
-
-
-
-
- Page 28 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
- bootstrap RPC;
- 1;
-
- File rpctest.pl: Perl test program for the RPC extension.
-
- use RPC;
-
- $netconf = getnetconfigent();
- $a = rpcb_gettime();
- print "time = $a\n";
- print "netconf = $netconf\n";
-
- $netconf = getnetconfigent("tcp");
- $a = rpcb_gettime("poplar");
- print "time = $a\n";
- print "netconf = $netconf\n";
-
-
- XXXXSSSS VVVVEEEERRRRSSSSIIIIOOOONNNN
- This document covers features supported by xsubpp 1.935.
-
- AAAAUUUUTTTTHHHHOOOORRRR
- Dean Roehrich <_r_o_e_h_r_i_c_h@_c_r_a_y._c_o_m> Jul 8, 1996
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 29 (printed 10/23/98)
-
-
-
-
-
-
- PPPPEEEERRRRLLLLXXXXSSSS((((1111)))) 22223333////JJJJuuuullll////99998888 ((((ppppeeeerrrrllll 5555....000000005555,,,, ppppaaaattttcccchhhh 00002222)))) PPPPEEEERRRRLLLLXXXXSSSS((((1111))))
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Page 30 (printed 10/23/98)
-
-
-
-
-
-
-